<script setup lang="ts">
import sha1 from 'sha1';
import dayjs from 'dayjs';
import { fileNameForUploadFile, uploadImageFile } from '/@/utils/file';
import { watch, onMounted, reactive } from 'vue';
import { chooseImage } from '@tarojs/taro';
import { Uploader as NutIconUploader, Close as NutIconClose } from '@nutui/icons-vue-taro';
import { getSysImgUrl } from '/@/utils/index';
import { appEvents } from '/@/utils/events';

const props = withDefaults(
  defineProps<{
    /**
     * 默认图片列表
     */
    defaultImageList?: { key: string; src: string }[];
    /**
     * 是否只读
     */
    readonly?: boolean;
    /**
     * 图片高度
     */
    height?: string;
    /**
     * 业务模块名称
     */
    module?: string;
    /**
     * 最大显示图片的数量
     */
    max?: number;
  }>(),
  {
    defaultImageList: () => [],
    readonly: false,
    height: '90px',
    module: 'other',
    max: 10,
  },
);
const emits = defineEmits<{
  (e: 'onChange', imageList: { key: string; src: string }[]): void;
}>();
const state = reactive<{
  /**
   * 是否显示图片预览
   */
  showImagePreview: boolean;
  /**
   * 图片列表
   */
  list: { key: string; src: string }[];
}>({
  showImagePreview: false,
  list: [],
});

/**
 * @function 上传图片
 */
function uploadImage() {
  chooseImage({
    count: 9,
    sizeType: ['original', 'compressed'],
    sourceType: ['album', 'camera'],
    success: (res) => {
      res.tempFiles.forEach(({ originalFileObj, path }) => {
        const suffix =
          originalFileObj?.name.substring(originalFileObj?.name.lastIndexOf('.')) || ''; //取文件名后缀
        const fileName = fileNameForUploadFile(suffix);
        const originalFileName = originalFileObj?.name || '';
        uploadImageFile(path, originalFileName, fileName, props.module, (url: string) => {
          state.list.push({
            key: sha1(`${dayjs().valueOf()}-${Math.random()}`) as string,
            src: url,
          });
          emits('onChange', state.list);
        });
      });
    },
  });
}

watch(props, (newProps) => {
  if (!newProps.defaultImageList || !newProps.defaultImageList.length) return;

  state.list = newProps.defaultImageList;
});

onMounted(() => {
  //显示图片
  state.list = props.defaultImageList;
  //处理图片
  appEvents.on('clearImageList', () => {
    state.list.splice(0, state.list.length);
  });
});
</script>

<template>
  <view v-bind="$attrs" class="app-upload-image__wrapper">
    <view
      v-for="(imgItem, imgIndex) in state.list"
      :key="imgItem.key"
      class="app-upload-image__item-wrapper"
      :style="{ height: props.height }"
    >
      <view class="app-upload-image__item">
        <view
          v-if="!props.readonly"
          class="app-upload-image__item-del-btn"
          @click="
            () => {
              state.list.splice(imgIndex, 1);
              emits('onChange', state.list);
            }
          "
        >
          <nut-icon-close size="10px" />
        </view>
        <image
          class="app-upload-image__img"
          mode="aspectFill"
          :src="getSysImgUrl(imgItem.src)"
          @click="
            () => {
              state.showImagePreview = true;
            }
          "
        />
      </view>
    </view>
    <!--当只读时或者到了最大上传图片限制都不能添加图片-->
    <view
      v-if="!props.readonly && !(props.max === props.defaultImageList.length)"
      class="app-upload-image__item-wrapper"
      :style="{ height: props.height }"
    >
      <view class="app-upload-image__item">
        <view class="app-upload-image__choose-image-btn" @click="uploadImage">
          <nut-icon-uploader />
        </view>
      </view>
    </view>
  </view>

  <nut-image-preview
    :show="state.showImagePreview"
    :images="
      state.list.map((i) => {
        return { src: getSysImgUrl(i.src) };
      })
    "
    @close="
      () => {
        state.showImagePreview = false;
      }
    "
  />
</template>

<style lang="scss">
@import './index.scss';
</style>
